package com.ppt.android.base.mvvm.v

import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.os.Bundle
import android.os.Looper
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.viewbinding.ViewBinding
import com.ppt.android.base.ktx.getAppViewModel
//import com.alibaba.android.arouter.launcher.ARouter
import com.ppt.android.base.mvvm.vm.BaseViewModel
import com.ppt.android.base.mvvm.vm.EventViewModel
import com.ppt.android.base.utils.*
import com.ppt.android.base.utils.network.AutoRegisterNetListener
import com.ppt.android.base.utils.network.NetworkStateChangeListener
import com.ppt.android.base.utils.network.NetworkTypeEnum
import com.ppt.android.base.view.LoadingDialog
import me.jessyan.autosize.AutoSizeCompat

/**
 * Activity基类
 *
 * @author ZouJiaCai
 * @since 8/27/20
 */
abstract class BaseFrameActivity<VB : ViewBinding, VM : BaseViewModel> : AppCompatActivity(),
    FrameView<VB>, NetworkStateChangeListener {

    protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
        BindingReflex.reflexViewBinding(javaClass, layoutInflater)
    }

    protected abstract val mViewModel: VM

    /**
     * 是否有 [RegisterEventBus] 注解，避免重复调用 [Class.isAnnotation]
     */
    private var mHaveRegisterEventBus = false
    private lateinit var loadingDialog: LoadingDialog

    /**
     * 全局唯一的事件viewModel
     */
    protected val eventViewModel: EventViewModel by lazy { getAppViewModel() }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(mBinding.root)

        // 根据子类是否有 RegisterEventBus 注解決定是否进行注册 EventBus
        if (javaClass.isAnnotationPresent(RegisterEventBus::class.java)) {
            mHaveRegisterEventBus = true
            EventBusUtils.register(this)
        }
        DisplayUtils.disableDisplayDpiChange(resources)

        // 创建 LoadingDialog 实例
        loadingDialog = LoadingDialog(this)

        setStatusBar()
        mBinding.initView()
        initNetworkListener()
        initObserve()
        initRequestData()
        showLoading()
    }

    /**
     * 初始化网络状态监听
     * @return Unit
     */
    private fun initNetworkListener() {
        lifecycle.addObserver(AutoRegisterNetListener(this))
    }

    /**
     * 设置状态栏
     * 子类需要自定义时重写该方法即可
     * @return Unit
     */
    open fun setStatusBar() {}

    /**
     * 网络类型更改回调
     * @param type Int 网络类型
     * @return Unit
     */
    override fun networkTypeChange(type: NetworkTypeEnum) {}

    /**
     * 网络连接状态更改回调
     * @param isConnected Boolean 是否已连接
     * @return Unit
     */
    override fun networkConnectChange(isConnected: Boolean) {
        toast(if (isConnected) "网络已连接" else "网络已断开")
    }

    override fun onDestroy() {
        // 根据子类是否有 RegisterEventBus 注解决定是否进行注册 EventBus
        if (mHaveRegisterEventBus) {
            EventBusUtils.unRegister(this)
        }
        if (::loadingDialog.isInitialized && loadingDialog.isShowing) {
            loadingDialog.dismiss()
        }
        super.onDestroy()
    }

    override fun getResources(): Resources {
        // 主要是为了解决 AndroidAutoSize 在横屏切换时导致适配失效的问题
        // 但是 AutoSizeCompat.autoConvertDensity() 对线程做了判断 导致Coil等图片加载框架在子线程访问的时候会异常
        // 所以在这里加了线程的判断 如果是非主线程 就取消单独的适配
        if (Looper.myLooper() == Looper.getMainLooper()) {
            AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources()))
        }
        return super.getResources()
    }

    private fun showLoading(){
        mViewModel.status.observe(this, Observer {
            when(it){
                StateLayoutEnum.HIDE->{
                    hideLoadingDialog()
                }
                StateLayoutEnum.LOADING->{
                    showLoadingDialog()
                }
                StateLayoutEnum.ERROR->{
                    hideLoadingDialog()
                }
                StateLayoutEnum.NO_DATA->{

                }
                StateLayoutEnum.SUCCESS->{

                }
            }
        })
    }

    private fun showLoadingDialog() {
        if (!::loadingDialog.isInitialized) {
            loadingDialog = LoadingDialog(this)
        }
        loadingDialog.show()
    }

    private fun hideLoadingDialog() {
        if (::loadingDialog.isInitialized && loadingDialog.isShowing) {
            loadingDialog.dismiss()
        }
    }

}